package robot;
import java.awt.Dimension;
import java.awt.GridLayout;

import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.text.AbstractDocument.BranchElement;

import robot.map.EnvironmentMap;
import robot.map.MemoryMap;



public class MainWindow {

	private JFrame mainWindow;

	private static boolean work;

	private RobotConsole consolePanel;
	private ControlPanel controlPanel;

	private EnvironmentMap environmentMap;
	private MemoryMap memoryMap;
	private Robot robot;

	/**
	 * Opens main window of application.
	 *
	 * @param args
	 */
	public static void main(String[] args) {
		work = false;
		new MainWindow();
	}

	private MainWindow() {
		mainWindow = new JFrame("Cleaning Robot");
		mainWindow.setBounds(100, 50, 1200, 700);
		mainWindow.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		mainWindow.setLayout(new GridLayout(2, 2));

		consolePanel = new RobotConsole();

		robot = new Robot(new Dimension(150, 150), this);

		environmentMap = new EnvironmentMap(consolePanel, robot);
		JScrollPane mapJScrollPane = new JScrollPane(environmentMap);
		mapJScrollPane.setPreferredSize(environmentMap.getSize());
		mainWindow.add(mapJScrollPane);

		memoryMap = new MemoryMap(consolePanel, robot);
		JScrollPane memoryJScrollPane = new JScrollPane(memoryMap);
		mainWindow.add(memoryJScrollPane);

		JScrollPane consoleJScrollPane = new JScrollPane(consolePanel.getjTextArea());
		mainWindow.add(consoleJScrollPane);

		controlPanel = new ControlPanel(consolePanel, this);
		JScrollPane controlJScrollPane = new JScrollPane(controlPanel.getJPanel());
		mainWindow.add(controlJScrollPane);

		mainWindow.setVisible(true);

		mainLoop();
	}

	public boolean isWorking() {
		return work;
	}

	public void setWorking(boolean w) {
		work = w;
	}

	public void setNewMap(byte[][] map) {
		environmentMap.setMap(map);
		memoryMap.clearMap();
	}

	public byte[][] getMap() {
		return environmentMap.getMap();
	}

	public JFrame getComponent() {
		return mainWindow;
	}

	private void mainLoop() {
		boolean problem = false;
		Dimension target = memoryMap.getTarget();
		Dimension tmp = null;
		Dimension[] before = new Dimension[3];
		before[0] = new Dimension(-1, -2);
		before[1] = new Dimension(-2, -2);
		before[2] = new Dimension(-3, -2);
		int count = 0;
		int it = 0;
		boolean passBlocker = false;

		while (true) {
			try {
				Thread.sleep(Const.SLEEP_TIME);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}



			if (work) {

				// START OF STEP

				if (passBlocker) {
					consolePanel.addText("Spróbuję ominąć przeszkodę.");
					if (robot.getPosition().equals(target)) {
						memoryMap.targetHit();
						target = memoryMap.getTarget();
						tmp = null;
					}

					if (problem) {
						consolePanel.addText("Podążam wzdłóż krawędzi!");
						do {
							robot.turnRight();
						} while (!robot.stepForward());
						if (robot.getPosition().equals(tmp)) {
							consolePanel.addText("Już tu byłem!");
							memoryMap.targetHit();
							target = memoryMap.getTarget();
							tmp = null;
							count = 0;
							passBlocker = false;
						}
						do {
							robot.turnLeft();
						} while (robot.stepForward());
						if (robot.getPosition().equals(tmp)) {
							consolePanel.addText("Już tu byłem!");
							memoryMap.targetHit();
							target = memoryMap.getTarget();
							tmp = null;
							count = 0;
							passBlocker = false;
						}
						problem = false;
					}
					else {
						if (tmp == null) {
							robot.rotate(target);
						}
						if (robot.stepForward()) {
							// great
						}
						else {
							problem = true;
							if (tmp == null) {
								tmp = robot.getPosition();
							}
						}
					}
				}
				else {
					if (robot.getPosition().equals(target)) {
						memoryMap.targetHit();
						target = memoryMap.getTarget();
						tmp = null;
					}

					if (problem) {
						consolePanel.addText("Wymijam!");
						do {
							robot.turnRight();
						} while (!robot.stepForward());
						if (robot.getPosition().equals(tmp)) {
							consolePanel.addText("Już tu byłem!");
							memoryMap.targetHit();
							target = memoryMap.getTarget();
							tmp = null;
						}
//						System.out.println(robot.getPosition());
//						System.out.println(before[0]);
//						System.out.println(before[1]);
//						System.out.println(before[2]);
//						System.out.println("x");
						if (robot.getPosition().equals(before[0]) ||
								robot.getPosition().equals(before[1]) ||
								robot.getPosition().equals(before[2])) {
//							System.out.println("!");
							count++;
//							System.out.println(count);
						}
						if (count>5) {
							passBlocker = true;
							tmp = null;
						}
						problem = false;
					}
					else {
						robot.rotate(target);
						if (robot.stepForward()) {
							// great
						}
						else {
							problem = true;
							if (tmp == null) {
								tmp = robot.getPosition();
							}
						}
					}
					
					before[it%3] = robot.getPosition();
				}

				it++;
				// END OF STEP

			}

			mainWindow.repaint();
		}
	}

	public RobotConsole getConsolePanel() {
		return consolePanel;
	}

	public EnvironmentMap getEnvironmentMap() {
		return environmentMap;
	}

	public MemoryMap getMemoryMap() {
		return memoryMap;
	}

}
